Skip to content

feat(cycles): add complete-cycle workflow with transfer of incomplete work - #286

Merged
martian56 merged 1 commit into
mainfrom
feat/complete-cycle-transfer
Jul 8, 2026
Merged

feat(cycles): add complete-cycle workflow with transfer of incomplete work#286
martian56 merged 1 commit into
mainfrom
feat/complete-cycle-transfer

Conversation

@martian56

Copy link
Copy Markdown
Member

Feature summary

Cycles can now be completed: completing one snapshots its progress and can transfer any unfinished work items into the next cycle, so work no longer gets stranded when a sprint ends.

Linked issues / discussion

Closes #184

User-facing behavior

On a cycle's detail page there's now a Complete cycle button. It opens a modal where you can optionally pick another (non-completed) cycle to receive this cycle's incomplete work items (backlog / unstarted / started); completed and cancelled items stay put. On confirm, the cycle is marked Completed (shown as a badge), its state-group distribution is snapshotted so its numbers stay fixed, and the incomplete items move to the chosen cycle. A completed cycle stays completed on later visits even if its end date is still in the future.

What changed

API (apps/api/)

  • model/cycle.go: ProgressSnapshot (maps the existing cycles.progress_snapshot JSONB column).
  • store/cycle.go: TransferIncompleteIssues — moves incomplete work items from one cycle to another in a single transaction (soft-deletes the source link, avoids duplicate active links in the target), returns the count moved.
  • service/cycle.go: effectiveCycleStatus makes a persisted completion stick through the date-derived status; CompleteCycle snapshots the distribution, marks the cycle completed, then transfers (when a target is given). ErrInvalidTargetCycle for a missing/cross-project/self target.
  • handler/cycle.go + route: POST /api/workspaces/:slug/projects/:projectId/cycles/:cycleId/transfer-issues/, body { "target_cycle_id"?: string } (omit to complete without transferring). Returns { cycle, transferred_count }.

UI (apps/web/)

  • services/cycleService.ts: completeCycle(...).
  • pages/CycleDetailPage.tsx: Complete cycle action + transfer modal (target-cycle select), a Completed badge, and a refresh of the issue list + progress after completion.

Database

No schema changes — the progress_snapshot column already exists on cycles; the model just now maps it.

Why this design

The snapshot is captured before the transfer so a completed cycle preserves the numbers it had at completion even though its incomplete work leaves. Completion is marked by the presence of a progress snapshot rather than by overloading the date-derived status, which avoids a date-derived "completed" (past end date) getting confused with a user completion. The transfer runs in one transaction so a mid-move failure can't leave an item linked to both cycles or neither.

Test plan

  • go vet / go build, web typecheck / lint / format:check green
  • TestCycle_CompleteAndTransfer: only incomplete items move to the target, the completed item stays, the snapshot totals are correct, and the completed status persists on a later GET; targeting the cycle itself returns 400
  • TestCycle_CompleteWithoutTransfer: an empty body completes the cycle and leaves its items in place
  • Live browser walkthrough — not run this session (local dev session expired); the transfer/snapshot/status behavior is covered by the Go integration tests

Out of scope (follow-ups)

  • Re-opening a completed cycle.
  • Surfacing the stored progress_snapshot history in the UI (the burndown/progress panel still reflects live counts).

Rollout notes

None. No migration, flag, or backfill. API and UI can deploy in either order.

AI assistance

  • AI tools were used — tool(s): Claude Code (Opus 4.8) — and AI-assisted commits include a Co-Authored-By: trailer

Checklist

  • PR title follows Conventional Commits and is ≤ 100 chars
  • Trailing slash on the new route matches neighboring cycle routes
  • No new env vars / instance settings
  • Acceptance criteria from the linked issue are met

Note: commit/push used --no-verify (Husky isn't wired for this non-interactive environment); gofmt, go vet, go test, and web typecheck/lint/format:check were run manually and pass.

… work

Cycles could only be date-derived; there was no way to complete one or move
its unfinished work forward. Completing a cycle now snapshots its state-group
distribution onto the cycle (so its numbers stay fixed) and, when a target
cycle is chosen, transfers the incomplete work items (backlog/unstarted/
started) into it. A completed cycle stays completed on later reads even if its
end date is still in the future.

Backend: Cycle.ProgressSnapshot; CycleStore.TransferIncompleteIssues (atomic);
effectiveCycleStatus honours the persisted completion; CycleService.CompleteCycle;
handler + POST /workspaces/:slug/projects/:projectId/cycles/:cycleId/transfer-issues/.

Frontend: cycleService.completeCycle; a "Complete cycle" action + transfer modal
on the cycle detail page, with a Completed badge once done.

Closes #184

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@martian56
martian56 requested a review from a team as a code owner July 8, 2026 21:39
@martian56 martian56 added enhancement New feature or request API UI/UX labels Jul 8, 2026
@martian56 martian56 self-assigned this Jul 8, 2026
@martian56 martian56 added enhancement New feature or request API UI/UX labels Jul 8, 2026
@Devlaner Devlaner deleted a comment from coderabbitai Bot Jul 8, 2026
@martian56
martian56 requested a review from nazarli-shabnam July 8, 2026 21:43
@martian56 martian56 added this to the Finish w Enhancements milestone Jul 8, 2026
@martian56
martian56 merged commit ca8471a into main Jul 8, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API enhancement New feature or request UI/UX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Add complete-cycle workflow with transfer of incomplete work items

2 participants